package com.Logistics.pddispatch.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.Logistics.truck.AddressCollectionFeignClient;
import com.Logistics.truck.AgencyScopeFeignClient;
import com.Logistics.OrderFeignClient;
import com.Logistics.pddispatch.dto.OrderClassifyDTO;
import com.Logistics.pddispatch.dto.OrderClassifyGroupDTO;
import com.Logistics.dto.OrderDto;
import com.Logistics.entity.Area;
import com.Logistics.entity.Order;
import com.Logistics.pddispatch.entity.OrderClassIfy;
import com.Logistics.pddispatch.entity.OrderClassIfyOrder;
import com.Logistics.entity.address.CityBean;
import com.Logistics.entity.address.DistrictBean;
import com.Logistics.entity.address.ProvinceBean;
import com.Logistics.entity.core.AgencyScope;
import com.Logistics.enums.OrderStatus;
import com.Logistics.feign.AreaFeignClient;
import com.Logistics.mycommon.include.Include;
import com.Logistics.pddispatch.mapper.OrderClassifyMapper;
import com.Logistics.pddispatch.service.OrderClassIfyOrderService;
import com.Logistics.pddispatch.service.OrderClassIfyService;
import com.Logistics.pddispatch.service.TaskOrderClassIfyService;
import com.Logistics.mycommon.tools.IDAlgorithm;
import com.Logistics.mycommon.tools.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class TaskOrderClassIfyServiceServiceImpl implements TaskOrderClassIfyService {
    @Autowired
    private AddressCollectionFeignClient addressCollectionFeignClient;
    @Autowired
    private AgencyScopeFeignClient agencyScopeFeignClient;
    @Autowired
    private OrderFeignClient orderFeignClient;
    @Autowired
    private AreaFeignClient areaFeignClient;
    @Autowired
    private OrderClassIfyService orderClassIfyService;
    @Autowired
    private OrderClassifyMapper orderClassifyMapper;
    @Autowired
    private OrderClassIfyOrderService orderClassIfyOrderService;
    /**
     * 订单分类
     * @param businessId 机构ID
     * @param jobId 任务ID
     * @param jobLogId 任务日志ID
     */
    @Override
    public List<OrderClassifyGroupDTO> execute(String businessId, String jobId, String jobLogId) {
        //用于存储分类后的订单数据
        List<OrderClassifyGroupDTO> orderClassifyGroupDTOS = new ArrayList<>();
        //用于存储当前机构下的所有订单
        List<OrderClassifyDTO> orderClassifyDTOList = new ArrayList<>();
        //查询当前网点下的所有订单(自己原有订单和转运订单)
        orderClassifyDTOList.addAll(buildNewOrder(businessId));
        orderClassifyDTOList.addAll(buildTransferOrder(businessId));
        //进行订单分类
        Map<String, List<OrderClassifyDTO>> collect =
                orderClassifyDTOList.stream().collect(Collectors.groupingBy(OrderClassifyDTO::groupBy));

        OrderClassifyGroupDTO.OrderClassifyGroupDTOBuilder builder = OrderClassifyGroupDTO.builder();
        collect.forEach((key, value) ->{
            builder.key(key);
            builder.orders(value.stream().map((item) -> item.getOrder()).collect(Collectors.toList()));
            OrderClassifyGroupDTO orderClassifyGroupDTO = builder.build();
            orderClassifyGroupDTOS.add(orderClassifyGroupDTO);
        });

        System.out.println(orderClassifyGroupDTOS);
        //将分类后的数据添加到分类表
        addOrderClassIfy(orderClassifyGroupDTOS,jobId,jobLogId);

        return orderClassifyGroupDTOS;
    }

    /**
     * 添加分类数据
     * @param orderClassifyGroupDTOS
     * @param jobId
     * @param jobLogId
     */
    @Transactional
    public void addOrderClassIfy(List<OrderClassifyGroupDTO> orderClassifyGroupDTOS, String jobId, String jobLogId) {
        orderClassifyGroupDTOS.forEach(item -> {
            if (item.isNew()){
                //新订单
                OrderClassIfy orderClassIfy = new OrderClassIfy();
                String orderClassIfyId = new IDAlgorithm(0L,0L).nextIdAsString();
                orderClassIfy.setId(orderClassIfyId);
                orderClassIfy.setClassify(item.getKey());
                orderClassIfy.setStart_agency_id(item.getStartAgencyId());
                orderClassIfy.setEnd_agency_id(item.getEndAgencyId());
                orderClassIfy.setJob_id(jobId);
                orderClassIfy.setJob_log_id(jobLogId);
                orderClassIfy.setTotal(item.getOrders().size());
                orderClassIfy.setCreate_date(new Date());
                Random random = new Random();
                List<OrderClassIfyOrder> orderClassIfyOrders = item.getOrders().stream().map(order -> {
                    int randomNumber = random.nextInt(10000) + 1;
                    Long orderClassIfyOrderId = Long.parseLong(new IDAlgorithm(0L,0L).nextIdAsString());
                    OrderClassIfyOrder orderClassIfyOrder = new OrderClassIfyOrder();
                    orderClassIfyOrder.setOrder_classify_id(orderClassIfyId);
                    orderClassIfyOrder.setId(String.valueOf(orderClassIfyOrderId+randomNumber));
                    orderClassIfyOrder.setOrder_id(order.getId());
                    return orderClassIfyOrder;
                }).collect(Collectors.toList());

                item.setId(orderClassIfyId);
                this.orderClassIfyService.save(orderClassIfy);
                this.orderClassIfyOrderService.saveBatch(orderClassIfyOrders);
            }else {
                //中转订单
                List<String> orderIds = item.getOrders().stream().map(order -> order.getId()).collect(Collectors.toList());
                QueryWrapper<OrderClassIfyOrder> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("order_id",orderIds);
                List<OrderClassIfyOrder> list = this.orderClassIfyOrderService.list(queryWrapper);

               Set<String> stringList =
                       list.stream().map(orderClassIfyOrder -> orderClassIfyOrder.getOrder_classify_id() ).collect(Collectors.toSet());
               if (CollectionUtils.isEmpty(stringList)){
                   item.setId("ERROR");
                   throwException("中转订单异常");
                   return;
               }
               item.setId(stringList.iterator().next());
            }
        });
    }

    /**
     * 查询中转订单
     * @param agency_id
     * @return
     */

    private List<OrderClassifyDTO> buildTransferOrder(String agency_id) {
        OrderDto orderDto = new OrderDto();
        orderDto.setCurrentAgencyId(agency_id);
        orderDto.setStatus(OrderStatus.ARRIVAL_TRANSFER.getCode());

        OrderClassifyDTO.OrderClassifyDTOBuilder builder = OrderClassifyDTO.builder();
        builder.currentAgencyId(agency_id);

        List<Order> orders = this.orderFeignClient.ObtainOrdersBasedOnConditions(orderDto);

        List<OrderClassifyDTO> list = orders.stream().map(item ->{
            try {
                builder.startAgencyId(getStartAgencyId(item));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            builder.order(item);
            builder.orderType(item.getOrderType());
            try {
                builder.endAgencyId(getEndAgencyId(item));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return builder.build();
        }).collect(Collectors.toList());

        return list;
    }

    /**
     * 获取起始机构
     * @param order
     * @return
     */

    private String getStartAgencyId(Order order) throws Exception {
        //获取寄件地址
        String address = getStartAddress(order);
        if (!StringUtils.hasText(address)){
            throwException("寄件完整地址为空");
        }

        //调用高德api 获取地址经纬度
        Map<String,String> map = MapUtils.aaa(address);
        StringBuffer location = new StringBuffer();
        location.append(map.get("lng")).append(",").append( map.get("lat"));
        if (!StringUtils.hasText(location)){
            throwException("寄件地址经纬度为空");
        }

        String intactAddress = MapUtils.getAMapByLngAndLat(map.get("lng"),map.get("lat"),null);
        if (!StringUtils.hasText(intactAddress)){
            throwException("寄件地址为空");
        }

        JSONObject jsonObject = (JSONObject) MapUtils.getAdCode(map.get("lng"),map.get("lat"));
        String adcode = jsonObject.getString("adcode");

        //TODO feign调用根据行政区域编号查询区域信息
        Area area = this.areaFeignClient.getAreaByAreaCode(adcode);
        if (ObjectUtils.isEmpty(area)){
            throwException("寄件区域信息为空");
        }

        if (!order.getSenderCountyId().equals(area.getArea_code())){
            throwException("寄件区域信息不一致");
        }

        //TODO feign调用根据区域编号查询网点
        List<AgencyScope> agencyScopeList = this.agencyScopeFeignClient.getAgencyScopeByAreaId(area.getArea_code());
        if (agencyScopeList.size() == 0 || agencyScopeList == null){
            throwException("网点信息为空");
        }

        //计算最近网点
        String agency_id = calculate(agencyScopeList,map.get("lng"),map.get("lat"));
        if (!StringUtils.hasText(agency_id)){
            throwException("计算起点所属网点错误");
        }

        return agency_id;
    }

    private String getStartAddress(Order order) {
            //查询省信息
            ProvinceBean provinceBean = this.addressCollectionFeignClient.QueryProvincesBasedOnId(order.getSenderProvinceId());
            //查询市信息
            CityBean cityBean = this.addressCollectionFeignClient.QueryCityBasedOnId(order.getSenderCityId());
            //查询区信息
            DistrictBean districtBean =
                    this.addressCollectionFeignClient.QueryDistrictsAndCountiesBasedOnId(order.getSenderCountyId());

            StringBuffer address = new StringBuffer();
            address.append(provinceBean.getName()).append(cityBean.getName()).append(districtBean.getName()).append(order.getSenderAddress());
            return address.toString();
    }

    /**
     * 查询所有订单
     * @param agency_id
     * @return
     */
    public List<OrderClassifyDTO> buildNewOrder(String agency_id){
        OrderDto orderDto = new OrderDto();
        orderDto.setCurrentAgencyId(agency_id);
        orderDto.setStatus(OrderStatus.OUTLETS_WAREHOUSE.getCode());

        OrderClassifyDTO.OrderClassifyDTOBuilder builder = OrderClassifyDTO.builder();
        builder.currentAgencyId(agency_id);

        List<Order> orders = this.orderFeignClient.ObtainOrdersBasedOnConditions(orderDto);

        List<OrderClassifyDTO> list = orders.stream().map(item ->{
            builder.startAgencyId(agency_id);
            builder.order(item);
            builder.orderType(item.getOrderType());
            try {
                builder.endAgencyId(getEndAgencyId(item));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return builder.build();
        }).collect(Collectors.toList());

        return list;
    }

    /**
     * 获取终点网点
     * @param order
     * @return
     */
    public String getEndAgencyId(Order order) throws Exception {
        //获取收件地址
        String address = getDeliveryAddress(order);
        if (!StringUtils.hasText(address)){
            throwException("收件完整地址为空");
        }

        //调用高德api 获取地址经纬度
        Map<String,String> map = MapUtils.aaa(address);
        StringBuffer location = new StringBuffer();
        location.append(map.get("lng")).append(",").append( map.get("lat"));
        if (!StringUtils.hasText(location)){
            throwException("地址经纬度为空");
        }

        String intactAddress = MapUtils.getAMapByLngAndLat(map.get("lng"),map.get("lat"),null);
        if (!StringUtils.hasText(intactAddress)){
            throwException("地址为空");
        }

        JSONObject jsonObject = (JSONObject) MapUtils.getAdCode(map.get("lng"),map.get("lat"));
        String adcode = jsonObject.getString("adcode");

        //TODO feign调用根据行政区域编号查询区域信息
        Area area = this.areaFeignClient.getAreaByAreaCode(adcode);
        if (ObjectUtils.isEmpty(area)){
            throwException("区域信息为空");
        }

        if (!order.getReceiverCountyId().equals(area.getArea_code())){
            throwException("区域信息不一致");
        }

        //TODO feign调用根据区域编号查询网点
        List<AgencyScope> agencyScopeList = this.agencyScopeFeignClient.getAgencyScopeByAreaId(area.getArea_code());
        if (agencyScopeList.size() == 0 || agencyScopeList == null){
            throwException("网点信息为空");
        }

        //计算最近网点
       String agency_id = calculate(agencyScopeList,map.get("lng"),map.get("lat"));
        if (!StringUtils.hasText(agency_id)){
            throwException("计算终点所属网点错误");
        }

        return agency_id;
    }

    /**
     * 计算最近网点
     * @param agencyScopeList 区域网点集合
     * @param
     */
    private String calculate(List<AgencyScope> agencyScopeList, String lng, String lat) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
            for (AgencyScope agencyScope : agencyScopeList) {
                // 使用正则表达式分割字符串
                String[] parts = agencyScope.getMuti_points().split("[\\[\\],]");

                // 去除空格和空字符串
                List<String> cleanParts = new ArrayList<>();
                for (String part : parts) {
                    if (!part.trim().isEmpty()) {
                        cleanParts.add(part);
                    }
                }
                // 判断是否包含
                boolean logo = Include.WhetherInclude(lng,lat,cleanParts.get(0),cleanParts.get(1),cleanParts.get(2));
                if (logo){
                    return agencyScope.getAgency_id();
                }
            }
        return null;
    }


    /**
     * 获取收件地址信息
     * @param order
     * @return
     */
    public String getDeliveryAddress(Order order){
        //查询省信息
        ProvinceBean provinceBean = this.addressCollectionFeignClient.QueryProvincesBasedOnId(order.getReceiverProvinceId());
        //查询市信息
        CityBean cityBean = this.addressCollectionFeignClient.QueryCityBasedOnId(order.getReceiverCityId());
        //查询区信息
        DistrictBean districtBean =
                this.addressCollectionFeignClient.QueryDistrictsAndCountiesBasedOnId(order.getReceiverCountyId());

        StringBuffer address = new StringBuffer();
        address.append(provinceBean.getName()).append(cityBean.getName()).append(districtBean.getName()).append(order.getReceiverAddress());
        return address.toString();
    }

    public void throwException(String message){
        try {
            throw new Exception(message);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws Exception {
        String data = "[112.963081,28.196505],54869";

        // 使用正则表达式分割字符串
        String[] parts = data.split("[\\[\\],]");

        // 去除空格和空字符串
        List<String> cleanParts = new ArrayList<>();
        for (String part : parts) {
            if (!part.trim().isEmpty()) {
                cleanParts.add(part);
            }
        }

        // 提取经度、纬度和另一个数值
        String longitude = cleanParts.get(0);
        String latitude = cleanParts.get(1);
        String number = cleanParts.get(2);

        // 打印结果
        System.out.println("经度: " + longitude);
        System.out.println("纬度: " + latitude);
        System.out.println("另一个数值: " + number);
    }
}

